package com.googlecode.continuity.core.server.mvc.validation;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import com.googlecode.continuity.core.client.User;
import com.googlecode.continuity.core.server.service.ConfigurationService;
import com.googlecode.continuity.core.server.service.UserService;

/**
 * UserValidator provides validation methods for {@link com.googlecode.continuity.core.client.User} objects.
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class UserValidator implements Validator {
  ConfigurationService configurationService;
  UserService userService;

  /**
   * Provides this validator with a reference to a user service.
   *
   * @param userService user service implementation
   */
  public void setUserService(UserService userService) {
    this.userService = userService;
  }

  /**
   * Provides this validator with a reference to a configuration service.
   *
   * @param configurationService configuration service implementation
   */
  public void setConfigurationService(ConfigurationService configurationService) {
    this.configurationService = configurationService;
  }

  /**
   * Checks whether the supplied class can be validated with this validator.
   *
   * @param aClass class of an object that needs validation
   * @return true if class is supported
   */
  public boolean supports(Class aClass) {
    // todo: support subclasses/continuityuser?
    return aClass.equals(User.class);
  }

  /**
   * Validates a {@link com.googlecode.continuity.core.client.User} object, making sure that its properties adhere to
   * boundaries given by the configuration.
   *
   * @param object user to be validated
   * @param errors error object into which errors can be written
   */
  public void validate(Object object, Errors errors) {
    User user = (User) object;

    // checking username
    if (user.getUsername().length() < configurationService.getValueInteger("core.user.name.length.min")) {
      errors.rejectValue("username", "error.username.tooShort",
          new Object[]{configurationService.getValueInteger("core.user.name.length.min")}, "");
    }

    if (user.getUsername().length() > configurationService.getValueInteger("core.user.name.length.max")) {
      errors.rejectValue("username", "error.username.tooLong",
          new Object[]{configurationService.getValueInteger("core.user.name.length.max")}, "");
    }

    if (userService.getUserByName(user.getUsername()) != null) {
      errors.rejectValue("username", "error.username.alreadyExists");
    }

    String[] forbiddenNames = configurationService.getValue("core.user.name.forbidden").split(",");
    for (String forbiddenName : forbiddenNames) {
      if (user.getUsername().equals(forbiddenName)) {
        errors.rejectValue("username", "error.username.forbidden");
      }
    }

    // todo: check email address
  }
}
